﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace GrapplingHookGameData
{
    public class LevelDefinition
    {
        private int width;
        public int Width
        {
            get { return width; }
            set { width = value; }
        }

        private int height;
        public int Height
        {
            get { return height; }
            set { height = value; }
        }

        private string mapData;
        public string MapData
        {
            get { return mapData; }
            set {
                mapData = value;
                tileIdices = parseMapData(mapData);
            }
        }

        private string tileSet;

        public string TileSet
        {
            get { return tileSet; }
            set { tileSet = value; }
        }

        private string collisionData;
        public string CollisionData
        {
            get { return collisionData; }
            set
            {
                collisionData = value;
                collisionBlocks = parseCollisionData(collisionData);
            }
        }

        private int[] tileIdices;
        [ContentSerializerIgnore]
        public int[] TileIdices
        {
            get { return tileIdices; }
        }

        private bool[] collisionBlocks;
        [ContentSerializerIgnore]
        public bool[] CollisionBlocks
        {
            get { return collisionBlocks; }
        }

        /// <summary>
        /// convert map string representation of indices to an int array
        /// </summary>
        /// <param name="mapStringRep"></param>
        /// <returns></returns>
        private int[] parseMapData(string mapStringRep)
        {
            string[] tileIndicesStr = mapStringRep.Split( new char[] {' ','\n'});
            int[] tileIdicesInt = new int[width*height];
            int i = 0;
            foreach (string index in tileIndicesStr)
            {
                try
                {
                    int intValue = int.Parse(index);
                    tileIdicesInt[i++] = intValue;
                }
                //if not a number we can parse, move on to next
                catch (FormatException) { }

            }
            return tileIdicesInt;
        }

        /// <summary>
        /// Convert string representation of collision data to a boolean array
        /// </summary>
        /// <param name="collisionStringRep"></param>
        /// <returns></returns>
        private bool[] parseCollisionData(string collisionStringRep)
        {
            string[] collisionStr = collisionStringRep.Split(new char[] { ' ', '\n' });
            bool[] collisionBool = new bool[width * height];
            int i = 0;
            foreach (string index in collisionStr)
            {
                try
                {
                    int intValue = int.Parse(index);
                    //collision values above 0 mean the block is solid, disregards direction
                    if (intValue > 0) collisionBool[i++] = true;
                    else collisionBool[i++] = false;
                }
                //if not a number we can parse, move on to next
                catch (FormatException) { }

            }
            return collisionBool;
        }
    }

    public class LevelContentReader : ContentTypeReader<LevelDefinition>
    {
        protected override LevelDefinition Read(ContentReader input, LevelDefinition existingInstance)
        {
            LevelDefinition level = new LevelDefinition();

            level.Width = input.ReadInt32();
            level.Height = input.ReadInt32();
            level.MapData = input.ReadString();
            level.TileSet = input.ReadString();
            level.CollisionData = input.ReadString();

            return level;
        }
    }
}
